#include "videoffmpeg.h"
#include <QImage>

namespace VideoFfmpeg
{
AVFrame    *m_pFrameRGB,*m_pFrameYUV;
uint8_t *m_rgbBuffer,*m_yuvBuffer;
struct SwsContext *m_img_convert_ctx;
int nwidth = 1920, nheight = 1080;


int avpicture_fill(AVFrame *picture, const uint8_t *ptr, enum AVPixelFormat pix_fmt, int width, int height)
{
    return av_image_fill_arrays(picture->data, picture->linesize, ptr, pix_fmt, width, height, 1);
}

//分配两个Frame，两段buff，一个转换上下文
void init(void)
{
    //为每帧图像分配内存
    m_pFrameYUV = av_frame_alloc();
    m_pFrameRGB = av_frame_alloc();// width和heigt为传入的分辨率的大小，分辨率有变化时可以以最大标准申请
    int numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, nwidth, nheight, 1);
    m_rgbBuffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
    int yuvSize = nwidth * nheight * 2;
    m_yuvBuffer = (uint8_t *)av_malloc(yuvSize);
    //特别注意sws_getContext内存泄露问题，
    //注意sws_getContext只能调用一次，在初始化时候调用即可，另外调用完后，在析构函数中使用sws_freeContext，将它的内存释放。
    //设置图像转换上下文
    m_img_convert_ctx = sws_getContext(nwidth, nheight, AV_PIX_FMT_YUYV422, nwidth, nheight, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
}

void play(unsigned char* pbuff_in,int nwidth,int nheight)
{
    avpicture_fill(m_pFrameRGB, m_rgbBuffer, AV_PIX_FMT_RGB24, nwidth, nheight);
    avpicture_fill(m_pFrameYUV, (uint8_t *)pbuff_in, AV_PIX_FMT_YUYV422, nwidth, nheight);
    //转换图像格式，将解压出来的YUV420P的图像转换为RGB的图像
    sws_scale(m_img_convert_ctx, (uint8_t const * const *) m_pFrameYUV->data,            m_pFrameYUV->linesize, 0, nheight, m_pFrameRGB->data, m_pFrameRGB->linesize);
    //把这个RGB数据 用QImage加载
    QImage tmpImg((uchar *)m_rgbBuffer,nwidth,nheight,QImage::Format_RGB888);
    tmpImg.save("/usr/app/zhangya/123.jpg");
    //把图像复制一份 传递给界面显示
    //m_mapImage[nWindowIndex] = tmpImg.copy();
}

void release(void)
{
    av_frame_free(&m_pFrameYUV);
    av_frame_free(&m_pFrameRGB);
    av_free(m_rgbBuffer);
    av_free(m_yuvBuffer);
    sws_freeContext(m_img_convert_ctx);
}

bool YuvToRgb_FFmpeg(unsigned char* pYUV,unsigned char* pRgb24,int width,int height)
{
    if (width < 1 || height < 1 || pYUV == NULL || pRgb24 == NULL) {
        return false;
    }

    AVFrame pFrameYUV,pFrameRGB;
    avpicture_fill(&pFrameYUV, pYUV, AV_PIX_FMT_YUYV422, width, height);

    //U,V互换
    uint8_t * ptmp=pFrameYUV.data[1];
    pFrameYUV.data[1]=pFrameYUV.data[2];
    pFrameYUV.data[2]=ptmp;

    avpicture_fill(&pFrameRGB, pRgb24, AV_PIX_FMT_RGB24, width,height);

    struct SwsContext* imgCtx = NULL;
    imgCtx = sws_getContext(width,height, AV_PIX_FMT_YUYV422,width,height, AV_PIX_FMT_RGB24,SWS_BILINEAR,0,0,0);

    if (imgCtx != NULL){
        sws_scale(imgCtx,pFrameYUV.data,pFrameYUV.linesize,0,height,pFrameRGB.data,pFrameRGB.linesize);
        if(imgCtx){
            sws_freeContext(imgCtx);
            imgCtx = NULL;
        }
        return true;
    }else{
        sws_freeContext(imgCtx);
        imgCtx = NULL;
        return false;
    }
}

}
